#include "textureeditor.h"
#include "../application.h"
#include "../document.h"
#include "../gameobjects/abstractobject.h"
#include "../gameobjects/texture.h"
#include "widgets/edittexturewidget.h"
#include <QPainter>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QUrl>

#define PREVIEW_FUNC() \
    EditTextureWidget* pView = qobject_cast<EditTextureWidget*>(m_view); \
    Q_ASSERT(pView); \
    TextureView* pPreview = qobject_cast<TextureView*>(pView->previewWidget()); \
    Q_ASSERT(pPreview);

#define TEXTURE_FUNC() \
    QPointer<Document> doc = Application::app().document(); \
    Q_ASSERT(doc); \
    QPointer<Texture> texture = qobject_cast<Texture*>(doc->currentObject()); \
    Q_ASSERT(texture);

TextureEditor::TextureEditor(QObject *parent)
    : AbstractEditor(parent)
{
}

bool TextureEditor::init()
{
    m_view = new EditTextureWidget;
    connect(m_view, SIGNAL(imageFilePathSelected(QString)),
                    this, SLOT(onImageFilePathSelected(QString)));

    PREVIEW_FUNC();
    connect(pPreview, SIGNAL(imageDropped(QString)),
                    this, SLOT(onImageFilePathSelected(QString)));

    return true;
}

void TextureEditor::activate()
{
    AbstractEditor::activate();

    TEXTURE_FUNC();
    PREVIEW_FUNC();
    pPreview->updateView(texture);

    // update lineEdit for texture path
    EditTextureWidget* pETView = qobject_cast<EditTextureWidget*>(m_view);
    pETView->setFileName(texture->fileName());
}

void TextureEditor::onImageFilePathSelected(const QString &path)
{
    TEXTURE_FUNC();

    texture->setFileName(path);

    PREVIEW_FUNC();
    pPreview->updateView(texture);

    // update lineEdit for texture path
    EditTextureWidget* pETView = qobject_cast<EditTextureWidget*>(m_view);
    pETView->setFileName(texture->fileName());
}

TextureEditor::TextureView::TextureView(QWidget *parent)
    : QWidget(parent)
{
    setAcceptDrops(true);
}

void TextureEditor::TextureView::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    QPixmap pm = m_texture->pixmap();
    if(!pm.isNull())
    {
        painter.drawPixmap(0, 0, pm);
        painter.save();
        painter.setPen(Qt::DotLine);
        painter.drawRect(pm.rect());
        painter.restore();
    }
    else
    {
        painter.save();
        QFont f = font();
        f.setPixelSize(20);
        painter.setFont(f);
        painter.drawText(rect(), Qt::AlignCenter, "Load or drag texture file...");
        painter.restore();
    }
}

void TextureEditor::TextureView::updateView(QPointer<Texture> texture)
{
    m_texture = texture;
    Q_ASSERT(m_texture);
    QPixmap pm = m_texture->pixmap();
    if(!pm.isNull())
    {
        resize(pm.size());
    }
    else
    {
        // force to resize to minimum size
        resize(1, 1);
    }

    update();
}


void TextureEditor::TextureView::dragEnterEvent(QDragEnterEvent *pEvent)
{
   QList<QUrl> listUrls = pEvent->mimeData()->urls();

   if(listUrls.size())
   {
        QString url = listUrls[0].toString();
        if(url.contains(".png"))
        {
            pEvent->acceptProposedAction();
        }
   }
}

void TextureEditor::TextureView::dropEvent(QDropEvent *pEvent)
{
    QString path = pEvent->mimeData()->urls().at(0).toString();
    path.remove("file:///");
    emit imageDropped(path);
}
